package com.ssyx.user.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ssyx.common.auth.AuthContextHolder;
import com.ssyx.common.exception.SsyxException;
import com.ssyx.common.result.Result;
import com.ssyx.common.result.ResultCodeEnum;
import com.ssyx.enums.UserType;
import com.ssyx.model.user.User;
import com.ssyx.user.service.UserService;
import com.ssyx.user.utils.ConstantPropertiesUtil;
import com.ssyx.utils.HttpClientUtils;
import com.ssyx.utils.JwtHelper;
import com.ssyx.vo.user.LeaderAddressVo;
import com.ssyx.vo.user.UserLoginVo;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * ClassName:WeixinApiController
 * Description:
 *
 * @Author kay
 * @Create 2024/5/14 17:38
 * @Version 1.0
 */
@RestController
@RequestMapping("/api/user/weixin")
public class WeixinApiController {

    @Autowired
    private UserService userService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Operation(summary = "微信登录获取openid(小程序)")
    @GetMapping("/wxLogin/{code}")
    public Result callback(@PathVariable String code) {
        //1.得到微信返回code临时票据值

        //2.拿着code + 小程序id + 小程序秘钥 使用HttpClients工具请求微信接口服务
        String wxOpenAppId = ConstantPropertiesUtil.WX_OPEN_APP_ID;
        String wxOpenAppSecret = ConstantPropertiesUtil.WX_OPEN_APP_SECRET;
        ////拼接请求地址和参数
        StringBuffer baseAccessTokenUrl = new StringBuffer()
                .append("https://api.weixin.qq.com/sns/jscode2session")
                .append("?appid=%s")
                .append("&secret=%s")
                .append("&js_code=%s")
                .append("&grant_type=authorization_code");
        String accessTokenUrl = String.format(baseAccessTokenUrl.toString(),
                wxOpenAppId,wxOpenAppSecret,code);
        ////使用HttpClients工具发送get请求,得到返回结果
        String result = null;
        try {
            result = HttpClientUtils.get(accessTokenUrl);
        } catch (Exception e) {
            throw new SsyxException(ResultCodeEnum.FETCH_ACCESSTOKEN_FAILD);
        }

        //3.得到请求结果中返回的两个值session_key 和 openid,其中openid是微信唯一标识
        JSONObject resultJson = JSONObject.parseObject(result);
        String accessToken = resultJson.getString("session_key");
        String openid = resultJson.getString("openid");

        //4.添加微信用户信息到数据库,根据openid
        ////操作user表
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>();
        wrapper.eq(User::getOpenId,openid);
        User user = userService.getOne(wrapper);
        ////判断是否是第一次使用微信授权登录,如何判断,在数据库中不存在该用户的openid则为第一次登录
        ////第一次登录的用户,封装相关数据后,存入数据库
        if(null == user){
            user = new User();
            user.setOpenId(openid);
            user.setNickName(openid);
            user.setPhotoUrl("");
            user.setUserType(UserType.USER);
            user.setIsNew(0);
            userService.save(user);
        }
        //5.根据userId查询提货点和团长信息,此信息已封装在LeaderAddressVo中
        //// 团长 user表 user_delivery表
        //// 提供点 leader表
        Long userId = user.getId();
        LeaderAddressVo leaderAddressVo = userService.getLeaderAddressVoByUserId(userId);

        //6.使用jwt工具,根据userId和userName生成token字符串
        String token = JwtHelper.createToken(userId, user.getNickName());

        //7.获取当前登录用户信息(此信息已封装在UserLoginVo中),放到redis中,设置有效时间
        UserLoginVo userLoginVo = userService.getUserLoginVo(userId);
        ////将userLoginVo转换成字符串,方便存储到redis中
        String stringUserLoginVo = JSON.toJSONString(userLoginVo);
        ////在redis中,key为openid ,value为userLoginVo对应的字符串,有效时间为7天
        stringRedisTemplate.opsForValue().set("user:ssyx:" + userId,stringUserLoginVo,7, TimeUnit.DAYS);

        //8.把需要的数据封装到map中返回到前端
        Map<String, Object> map = new HashMap<>();
        map.put("user", user);
        map.put("leaderAddressVo", leaderAddressVo);
        map.put("token", token);
        return Result.ok(map);
    }

    //更新用户昵称与头像
    @PostMapping("/auth/updateUser")
    public Result updateUser(@RequestBody User user) {
        Long userId = AuthContextHolder.getUserLoginVo().getUserId();
        User user1 = userService.getById(userId);
        //把昵称更新为微信用户
        user1.setNickName(user.getNickName().replaceAll("[ue000-uefff]", "*"));
        user1.setPhotoUrl(user.getPhotoUrl());
        userService.updateById(user1);
        return Result.ok(null);
    }

}
